<?php

/*
 * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between
 * Copyright (C) 2006-2009 Dan Fuhry
 *
 * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for details.
 */

function page_Admin_UserRanks()
{
	global $db, $session, $paths, $template, $plugins; // Common objects
	global $lang;
	if ( $session->auth_level < USER_LEVEL_ADMIN || $session->user_level < USER_LEVEL_ADMIN )
	{
		$login_link = makeUrlNS('Special', 'Login/' . $paths->nslist['Special'] . 'Administration', 'level=' . USER_LEVEL_ADMIN, true);
		echo '<h3>' . $lang->get('adm_err_not_auth_title') . '</h3>';
		echo '<p>' . $lang->get('adm_err_not_auth_body', array( 'login_link' => $login_link )) . '</p>';
		return;
	}
	
	// This should be a constant somewhere
	$protected_ranks = array(
			RANK_ID_MEMBER,
			RANK_ID_MOD,
			RANK_ID_ADMIN,
			RANK_ID_GUEST
		);
	
	if ( $paths->getParam(0) == 'action.json' )
	{
		// ajax call, try to decode json request
		header('Content-type: application/json');
		
		if ( !isset($_POST['r']) )
		{
			echo enano_json_encode(array(
					'mode' => 'error',
					'error' => 'Missing JSON request payload'
				));
			return true;
		}
		try
		{
			$request = enano_json_decode($_POST['r']);
		}
		catch ( Exception $e )
		{
			echo enano_json_encode(array(
					'mode' => 'error',
					'error' => 'Invalid JSON request payload'
				));
			return true;
		}
		
		if ( !isset($request['mode']) )
		{
			echo enano_json_encode(array(
					'mode' => 'error',
					'error' => 'JSON request payload does not contain required parameter "mode"'
				));
			return true;
		}
		
		// we've got it
		switch ( $request['mode'] )
		{
			case 'get_rank':
				// easy enough, get a rank from the DB
				$rank_id = intval(@$request['rank_id']);
				if ( empty($rank_id) )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => 'Missing rank ID'
						));
					return true;
				}
				// query and fetch
				$q = $db->sql_query('SELECT rank_id, rank_title, rank_style FROM ' . table_prefix . "ranks WHERE rank_id = $rank_id;");
				if ( !$q || $db->numrows() < 1 )
					$db->die_json();
				
				$row = $db->fetchrow();
				$db->free_result();
				
				// why does mysql do this?
				$row['rank_id'] = intval($row['rank_id']);
				echo enano_json_encode($row);
				break;
			case 'save_rank':
				// easy enough, get a rank from the DB
				$rank_id = intval(@$request['rank_id']);
				// note - an empty rank_style field is permitted
				if ( empty($rank_id) )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => 'Missing rank ID'
						));
					return true;
				}
				
				if ( empty($request['rank_title']) )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => $lang->get('acpur_err_missing_rank_title')
						));
					return true;
				}
				
				// perform update
				$rank_title = $db->escape($request['rank_title']);
				$rank_style = $db->escape(@$request['rank_style']);
				$q = $db->sql_query('UPDATE ' . table_prefix . "ranks SET rank_title = '$rank_title', rank_style = '$rank_style' WHERE rank_id = $rank_id;");
				
				// regenerate the ranks cache
				generate_cache_userranks();
				
				echo enano_json_encode(array(
						'mode' => 'success'
					));
				break;
			case 'create_rank':
				if ( empty($request['rank_title']) )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => $lang->get('acpur_err_missing_rank_title')
						));
					return true;
				}
				
				$rank_title = $db->escape($request['rank_title']);
				$rank_style = $db->escape(@$request['rank_style']);
				
				// perform insert
				$q = $db->sql_query('INSERT INTO ' . table_prefix . "ranks ( rank_title, rank_style ) VALUES\n"
													. "  ( '$rank_title', '$rank_style' );");
				if ( !$q )
					$db->die_json();
				
				$rank_id = $db->insert_id();
				if ( !$rank_id )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => 'Refetch of rank ID failed'
						));
					return true;
				}
				
				// regenerate the ranks cache
				generate_cache_userranks();
				
				echo enano_json_encode(array(
						'mode' => 'success',
						'rank_id' => $rank_id
					));
				break;
			case 'delete_rank':
				// nuke a rank
				$rank_id = intval(@$request['rank_id']);
				if ( empty($rank_id) )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => 'Missing rank ID'
						));
					return true;
				}
				
				// is this rank protected (e.g. a system rank)?
				if ( in_array($rank_id, $protected_ranks) )
				{
					echo enano_json_encode(array(
							'mode' => 'error',
							'error' => $lang->get('acpur_err_cant_delete_system_rank')
						));
					return true;
				}
				
				// unset any user and groups that might be using it
				$q = $db->sql_query('UPDATE ' . table_prefix . "users SET user_rank = NULL WHERE user_rank = $rank_id;");
				if ( !$q )
					$db->die_json();
				$q = $db->sql_query('UPDATE ' . table_prefix . "groups SET group_rank = NULL WHERE group_rank = $rank_id;");
				if ( !$q )
					$db->die_json();
				
				// now remove the rank itself
				$q = $db->sql_query('DELETE FROM ' . table_prefix . "ranks WHERE rank_id = $rank_id;");
				if ( !$q )
					$db->_die();
				
				// regenerate the ranks cache
				generate_cache_userranks();
				
				echo enano_json_encode(array(
						'mode' => 'success'
					));
				break;
			default:
				echo enano_json_encode(array(
					'mode' => 'error',
					'error' => 'Unknown requested operation'
				));
			return true;
		}
		return true;
	}
	
	// draw initial interface
	// yes, four paragraphs of introduction. Suck it up.
	echo '<h3>' . $lang->get('acpur_heading_main') . '</h3>';
	echo '<p>' . $lang->get('acpur_intro_para1') . '</p>';
	echo '<p>' . $lang->get('acpur_intro_para2') . '</p>';
	echo '<p>' . $lang->get('acpur_intro_para3') . '</p>';
	echo '<p>' . $lang->get('acpur_intro_para4') . '</p>';
	
	// fetch ranks
	$q = $db->sql_query('SELECT rank_id, rank_title, rank_style FROM ' . table_prefix . "ranks ORDER BY rank_title ASC;");
	if ( !$q )
		$db->_die();
	
	echo '<div class="rankadmin-left" id="admin_ranks_container_left">';
	while ( $row = $db->fetchrow() )
	{
		// format rank according to what its users look like
		// rank titles can be stored as language strings, so have the language manager fetch this
		// normally it refetches (which takes time) if a string isn't found, but it won't try to fetch
		// a string that isn't in the category_stringid format
		$rank_title = $lang->get($row['rank_title']);
		// FIXME: make sure htmlspecialchars() is escaping quotes and backslashes
		echo '<a href="#rank_edit:' . $row['rank_id'] . '" onclick="ajaxInitRankEdit(' . $row['rank_id'] . '); return false;" class="rankadmin-editlink" style="' . htmlspecialchars($row['rank_style']) . '" id="rankadmin_editlink_' . $row['rank_id'] . '">' . htmlspecialchars($rank_title) . '</a> ';
	}
	echo '<a href="#rank_create" onclick="ajaxInitRankCreate(); return false;" class="rankadmin-editlink rankadmin-createlink" id="rankadmin_createlink">' . $lang->get('acpur_btn_create_init') . '</a> ';
	echo '</div>';
	
	echo '<div class="rankadmin-right" id="admin_ranks_container_right">';
	echo $lang->get('acpur_msg_select_rank');
	echo '</div>';
	echo '<span class="menuclear"></span>';
}

?>
